#!/bin/bash

# from: https://raw.githubusercontent.com/letseeqiji/oneinstall/master/golang/goinstall.sh

# todo: gopls
#
# echo 📕: error message
# echo 📙: warning message
# echo 📗: ok status message
# echo 📘: action message
# echo 📔: Or anything you like and want to recognize immediately by color
# echo 💩: Or with a specific emoji

# cecho "RED" "Helloworld"
# cecho(){
#     RED="\033[0;31m"
#     GREEN="\033[0;32m"
#     YELLOW="\033[1;33m"
#     NC="\033[0m" # No Color
#     printf "${!1}${2} ${NC}\n"
# }

# TODO:  <20-08-21, yourname> # go tool and go/bin add to path

export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:$PATH
readonly installPath="/usr/local"
readonly pathFile="/etc/profile"
clear

info()   { echo -e -n "$@"; }
infoln() { echo -e -n "$@\n"; }
notice()   { echo -e -n "\033[01;32m$@\033[0m"; }
noticeln() { echo -e -n "\033[01;32m$@\n\033[0m"; }
error()    { echo -e -n "\033[01;31m$@\033[0m"; }
errorln()  { echo -e -n "\033[01;31m$@\n\033[0m"; }


install_go()
{
    notice "Install GO [y|Y]:"
    read -n1 install_choose
    echo -e "\n"
    if [[ $install_choose == 'y' ]] || [[ $install_choose == 'Y' ]]; then
        infoln "Please waiting ... "
    else
        infoln "Cancel install ..."
        return 0
    fi

    noticeln "[1] Detect environment"

    go version &> /dev/null
    if [ $? -eq 0 -a x$1 != x"force" ]; then
        errorln "Error: GO has already installed"
        return 1
    fi

    ping www.studygolang.com -c 1 &> /dev/null
    if [ $? -ne 0 ]; then
        errorln "Error: Network unreached"
        return 1
    fi

    if [ $(id -u) != "0" ]; then
        errorln "Error: must root"
        return 1
    fi

    curl --version &> /dev/null
    if [ $? -ne 0 ]; then
        errorln "Error: curl not exists"
        return 1
    fi

    noticeln "[2] Download and install software"

    if [ ! -f "$pathFile" ]; then
        infoln "$pathFile not exists"
        return 1
    fi

    gourl=$(curl -s  https://studygolang.com/dl |  \
        sed -n '/dl\/golang\/go.*\.linux-amd64\.tar\.gz/p' | \
        sed -n '1p' | sed -n '/1/p' | \
        awk 'BEGIN{FS="\""}{print $4}')
    goweb="https://studygolang.com"
    gourl="${goweb}${gourl}"

    # install package already exist
    gosrc=$(ls | grep linux-amd64.tar.gz | sed -n '1p')
    if [ ! -f "$gosrc" ]; then
        wget -qc $gourl
        if [ $? -ne 0 ]; then
            errorln "Download go package failed"
            return 1
        fi
    else
        infoln "File already existed: $gosrc" 
    fi
    gosrc=$(ls | grep linux-amd64.tar.gz | sed -n '1p')

    # use local package 
    if [[ -f "$gosrc" ]] && [[ -d "$installPath" ]] ; then
        infoln "Start install ..." 
        /bin/rm -rf $installPath/go
        tar -C /usr/local -zxf $gosrc
        if [ $? -ne 0 ]; then
            errorln "Error: untar failed"
            return 1
        fi
    fi

    noticeln "[3] configuration"
    go env -w GO111MODULE=on
    go env -w GOPROXY=https://goproxy.cn,direct
    go env -w CGO_ENABLED=0

    if ! grep -q tag_go $pathFile; then
        echo 'export GOROOT=/usr/local/go # tag_go' >> $pathFile
        echo 'export PATH=$PATH:$GOROOT/bin # tag_go' >> $pathFile
    fi

    source $pathFile

    # 4  check install result
    noticeln "[4] Check version"
    go version
    if [ $? -eq 0 ]; then
        infoln "Install succeed "
    else
        errorln "Error: Install failed "
    fi
}

uninstall_go()
{
    notice "Uninstall GO [y|Y]:"
    read -n1 install_choose
    echo -e "\n"
    if [[ $install_choose == 'y' ]] || [[ $install_choose == 'Y' ]]; then
        infoln "Please waiting ... "
    else
        infoln "Cancel install ..."
        return 0
    fi

    /bin/rm -rf $installPath/go
    sed -i '/tag_go/d' $pathFile
    source $pathFile
    infoln "Uninstall succeed"
}

upgrade_go()
{
    go version &> /dev/null
    if [ $? -ne 0 ]; then
        errorln "Error: GO not installed"
        return 1
    fi

    infoln "Detect version ..."

    local_version=$(go version | tr -cd "[0-9]")
    infoln "Current version: ${local_version}"

    new_version=$(curl -s https://studygolang.com/dl |  \
        sed -n '/dl\/golang\/go.*\.linux-amd64\.tar\.gz/p' | \
        sed -n '1p' | sed -n '/1/p' | awk 'BEGIN{FS="\""}{print $4}' | \
        awk 'BEGIN{FS="/"}{print $4}' | tr -cd "[0-9]" )
    infoln "Latest  version: ${new_version}"

    if [ $local_version -eq $new_version ]; then
        infoln "The current version is up to date"
    elif [ $local_version -lt $new_version ]; then
        infoln "Removing old version"
        uninstall_go
        infoln "Install new version"
        install_go 
    fi
}

install_bin()
{
    go install github.com/cweill/gotests/...@latest
    go install github.com/davidrjenni/reftools/cmd/fillstruct@master
    go install github.com/fatih/gomodifytags@latest
    go install github.com/fatih/motion@latest
    go install github.com/go-delve/delve/cmd/dlv@latest
    go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
    go install github.com/haya14busa/goplay/cmd/goplay@latest
    go install github.com/josharian/impl@latest
    go install github.com/josharian/impl@main
    go install github.com/jstemmer/gotags@master
    go install github.com/kisielk/errcheck@latest
    go install github.com/klauspost/asmfmt/cmd/asmfmt@latest
    go install github.com/koron/iferr@master
    go install github.com/mgechev/revive@latest
    go install github.com/rogpeppe/godef@latest
    go install golang.org/x/tools/cmd/goimports@master
    go install golang.org/x/tools/gopls@latest
    go install honnef.co/go/tools/cmd/staticcheck@latest
    go install mvdan.cc/gofumpt@latest

    return 0
}

PS3="Select item please: "
items=( \
    "Install golang [ must root ]" \
    "Upgrade golang [ must root ]" \
    "Uninstall golang [ must root ]" \
    "Intall binary [ must root ]" \
)

while true; do
    select item in "${items[@]}" Quit; do
        case $REPLY in
            1) install_go; break;;
            2) upgrade_go; break;;
            3) uninstall_go; break;;
            4) install_bin; break;;
            $((${#items[@]}+1))) echo "We're done!"; break 2;;
            *) echo "Ooops - unknown choice $REPLY"; break;
        esac
    done
done
